home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / mamesrc / src / amiga / inputs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  20.1 KB  |  793 lines

  1. /**************************************************************************
  2.  *
  3.  * Copyright (C) 1999 Mats Eirik Hansen (mats.hansen@triumph.no)
  4.  *
  5.  * $Id: inputs.c,v 1.1 1999/04/28 18:56:13 meh Exp meh $
  6.  *
  7.  * $Log: inputs.c,v $
  8.  * Revision 1.1  1999/04/28 18:56:13  meh
  9.  * Initial revision
  10.  *
  11.  *
  12.  *************************************************************************/
  13.  
  14. #include <clib/alib_protos.h>
  15.  
  16. #include <exec/types.h>
  17. #include <exec/io.h>
  18. #include <exec/memory.h>
  19. #include <exec/errors.h>
  20. #include <dos/dosextens.h>
  21. #include <dos/dostags.h>
  22. #include <intuition/intuition.h>
  23. #include <libraries/lowlevel.h>
  24. #include <devices/inputevent.h>
  25. #include <devices/gameport.h>
  26. #include <devices/timer.h>
  27. #include <devices/input.h>
  28.  
  29. #include <inline/exec.h>
  30. #include <inline/dos.h>
  31. #include <inline/intuition.h>
  32. #include <inline/utility.h>
  33. #include <inline/keymap.h>
  34.  
  35. #ifdef POWERUP
  36. #include <powerup/ppclib/memory.h>
  37. #include <inline/ppc.h>
  38. #endif
  39.  
  40. #define LOWLEVEL_BASE_NAME inputs->LowLevelBase
  41. #include <inline/lowlevel.h>
  42.  
  43. #include <macros.h>
  44.  
  45. #define INPUTS_PRIVATE
  46. #include "inputs.h"
  47.  
  48. extern struct Library *SysBase;
  49. extern struct Library *DOSBase;
  50. extern struct Library *IntuitionBase;
  51. extern struct Library *UtilityBase;
  52. extern struct Library *KeymapBase;
  53.  
  54. #ifdef POWERUP
  55. extern struct Library *PPCLibBase;
  56.  
  57. static inline APTR memAlloc(ULONG size)
  58. {
  59.   return(PPCAllocVec(size, MEMF_PUBLIC|MEMF_CLEAR|MEMF_NOCACHESYNCPPC|MEMF_NOCACHESYNCM68K));
  60. }
  61.  
  62. static inline void memFree(APTR mem)
  63. {
  64.   PPCFreeVec(mem);
  65. }
  66. #else
  67. static inline APTR memAlloc(ULONG size)
  68. {
  69.   return(AllocVec(size, MEMF_PUBLIC|MEMF_CLEAR));
  70. }
  71.  
  72. static inline void memFree(APTR mem)
  73. {
  74.   FreeVec(mem);
  75. }
  76. #endif
  77.  
  78. void IAllocPort(struct Inputs *inputs, LONG portnum);
  79. void IFreePort(struct Inputs *inputs, LONG portnum);
  80. void IEnablePort(struct Inputs *inputs, LONG pornum);
  81. void IDisablePort(struct Inputs *inputs, LONG portnum);
  82. void IUpdatePort(struct Inputs *inputs, LONG portnum);
  83. void IUpdateKeys(struct Inputs *inputs);
  84.  
  85. struct Inputs *AllocInputs(Tag tags,...)
  86. {
  87.   struct Inputs *inputs;
  88.   struct IKeyMap  *keymap;
  89.   struct TagItem  *tag, *tstate;
  90.   UBYTE     buf[2];
  91.   LONG      i, t;
  92.   int       use_ticks;
  93.  
  94.   if((inputs = (struct Inputs *) AllocVec(sizeof(struct Inputs), MEMF_CLEAR)))
  95.   {
  96.     tag = FindTagItem(IA_KeyMap, (struct TagItem *) &tags);
  97.  
  98.     if(tag)
  99.       keymap  = (struct IKeyMap *) tag->ti_Data;
  100.     else
  101.       keymap  = NULL;
  102.  
  103.     t = 0;
  104.  
  105.     if(keymap)
  106.     {
  107.       for(i = 0, t = 0; keymap[i].Key; i++)
  108.       {
  109.         if(keymap[i].Key > t)
  110.           t = keymap[i].Key;
  111.       }
  112.     }
  113.  
  114.     inputs->Ports[0]  = (struct IPort *) memAlloc(2*sizeof(struct IPort)+t+1);
  115.  
  116.     if(inputs->Ports[0])
  117.     {
  118.       inputs->Ports[1]  = &inputs->Ports[0][1];
  119.  
  120.       inputs->LowLevelBase  = OpenLibrary("lowlevel.library", 0);
  121.  
  122.       use_ticks = FALSE;
  123.  
  124.       tstate = (struct TagItem *) &tags;
  125.       while((tag = NextTagItem(&tstate)))
  126.       {
  127.         switch(tag->ti_Tag)
  128.         {
  129.           case IA_Port1:
  130.             inputs->Ports[0]->Type  = tag->ti_Data;
  131.             break;
  132.           case IA_Port2:
  133.             inputs->Ports[1]->Type  = tag->ti_Data;
  134.             break;
  135.           case IA_P1AutoFireRate:
  136.             if(tag->ti_Data)
  137.               inputs->Ports[0]->AutoFireTime  = 500000 / tag->ti_Data;
  138.             break;
  139.           case IA_P2AutoFireRate:
  140.             if(tag->ti_Data)
  141.               inputs->Ports[1]->AutoFireTime  = 500000 / tag->ti_Data;
  142.             break;
  143.           case IA_P1BlueEmuTime:
  144.             if(tag->ti_Data)
  145.               inputs->Ports[0]->BlueEmuTime = 100000 * tag->ti_Data;
  146.             break;
  147.           case IA_P2BlueEmuTime:
  148.             if(tag->ti_Data)
  149.               inputs->Ports[1]->BlueEmuTime = 100000 * tag->ti_Data;
  150.             break;
  151.           case IA_Window:
  152.             inputs->Window  = (struct Window *) tag->ti_Data;
  153.             break;
  154.           case IA_RefreshHook:
  155.             inputs->RefreshHook = (struct Hook *) tag->ti_Data;
  156.             break;
  157.           case IA_MenuHook:
  158.             inputs->MenuHook  = (struct Hook *) tag->ti_Data;
  159.             break;
  160.           case IA_UseTicks:
  161.             use_ticks = TRUE;
  162.             break;
  163.           case IA_IDCMPHook:
  164.             inputs->IDCMPHook = (struct Hook *) tag->ti_Data;
  165.             break;
  166.         }
  167.       }
  168.  
  169.       if(inputs->Window)
  170.       {
  171.         if(use_ticks)
  172.           ModifyIDCMP(inputs->Window, inputs->Window->IDCMPFlags|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_INTUITICKS);
  173.         else
  174.           ModifyIDCMP(inputs->Window, inputs->Window->IDCMPFlags|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW);
  175.       }
  176.       
  177.       if(keymap)
  178.       {
  179.         inputs->Keys    = (BYTE *) &inputs->Ports[0][2];
  180.  
  181.         for(i = 0; keymap[i].Key; i++)
  182.         {
  183.           if(keymap[i].Key & IKEY_RAW)
  184.             inputs->RawKeys[keymap[i].Key & (~IKEY_RAW)] = keymap[i].Code;
  185.           else if(keymap[i].Key != IKEY_NONE)
  186.           {
  187.             if(MapANSI(((UBYTE *) &keymap[i].Key) + 3, 1, buf, 1, NULL) == 1)
  188.             {
  189.               if(!buf[1])
  190.                 inputs->RawKeys[buf[0] & IKEY_RAWMASK] = keymap[i].Code;
  191.             }
  192.           }
  193.         }
  194.  
  195.         if(inputs->Window)
  196.           ModifyIDCMP(inputs->Window, inputs->Window->IDCMPFlags|IDCMP_RAWKEY);
  197.       }
  198.  
  199.       if(inputs->Ports[0]->Type)
  200.       {
  201.         if(!OpenDevice("input.device", NULL, (struct IORequest *) &inputs->InputRequest, NULL))
  202.         {
  203.           BYTE  dummyport = 2;
  204.  
  205.           inputs->InputRequest.io_Data    = &dummyport;
  206.           inputs->InputRequest.io_Flags   = IOF_QUICK;
  207.           inputs->InputRequest.io_Length    = 1;
  208.           inputs->InputRequest.io_Command = IND_SETMPORT;
  209.           BeginIO((struct IORequest *) &inputs->InputRequest);
  210.         }
  211.  
  212.         IAllocPort(inputs, 0);
  213.       }
  214.  
  215.       if(inputs->Ports[1]->Type)
  216.         IAllocPort(inputs, 1);
  217.  
  218.       if(inputs->Window)
  219.         inputs->SignalMask  = 1<<inputs->Window->UserPort->mp_SigBit;
  220.  
  221.       if(inputs->Ports[0] && inputs->Ports[0]->MsgPort)
  222.         inputs->SignalMask  |= 1<<inputs->Ports[0]->MsgPort->mp_SigBit;
  223.  
  224.       if(inputs->Ports[1] && inputs->Ports[1]->MsgPort)
  225.         inputs->SignalMask  |= 1<<inputs->Ports[1]->MsgPort->mp_SigBit;
  226.  
  227.       inputs->Enabled = TRUE;
  228.  
  229.       return(inputs);
  230.     }
  231.  
  232.     FreeVec(inputs);
  233.   }
  234.  
  235.   return(NULL);
  236. }
  237.  
  238. void FreeInputs(struct Inputs *inputs)
  239. {
  240.   if(inputs->Ports[0]->Type)
  241.     IFreePort(inputs, 0);
  242.  
  243.   if(inputs->Ports[1]->Type)
  244.     IFreePort(inputs, 1);
  245.  
  246.   if(inputs->LowLevelBase)
  247.     CloseLibrary(inputs->LowLevelBase);
  248.  
  249.   if(inputs->InputRequest.io_Device)
  250.   {
  251.     BYTE  dummyport = 0;
  252.  
  253.     inputs->InputRequest.io_Data    = &dummyport;
  254.     inputs->InputRequest.io_Flags   = IOF_QUICK;
  255.     inputs->InputRequest.io_Length    = 1;
  256.     inputs->InputRequest.io_Command = IND_SETMPORT;
  257.     BeginIO((struct IORequest *) &inputs->InputRequest);
  258.     CloseDevice((struct IORequest *) &inputs->InputRequest);
  259.   }
  260.  
  261.   memFree(inputs->Ports[0]);
  262.  
  263.   FreeVec(inputs);
  264. }
  265.  
  266. void IEnable(struct Inputs *inputs)
  267. {
  268.   if(!inputs->Enabled && inputs->Ports[0]->Type)
  269.   {
  270.     BYTE dummyport = 2;
  271.  
  272.     IEnablePort(inputs, 0);
  273.  
  274.     inputs->InputRequest.io_Data    = &dummyport;
  275.     inputs->InputRequest.io_Flags   = IOF_QUICK;
  276.     inputs->InputRequest.io_Length    = 1;
  277.     inputs->InputRequest.io_Command   = IND_SETMPORT;
  278.     BeginIO((struct IORequest *) &inputs->InputRequest);
  279.   }
  280.  
  281.   inputs->Enabled = FALSE;
  282. }
  283.  
  284. void IDisable(struct Inputs *inputs)
  285. {
  286.   if(inputs->Enabled && inputs->Ports[0]->Type)
  287.   {
  288.     BYTE dummyport = 0;
  289.  
  290.     IDisablePort(inputs, 0);
  291.  
  292.     inputs->InputRequest.io_Data    = &dummyport;
  293.     inputs->InputRequest.io_Flags   = IOF_QUICK;
  294.     inputs->InputRequest.io_Length    = 1;
  295.     inputs->InputRequest.io_Command   = IND_SETMPORT;
  296.     BeginIO((struct IORequest *) &inputs->InputRequest);
  297.   }
  298.  
  299.   inputs->Enabled = FALSE;
  300. }
  301.  
  302. void IUpdate(struct Inputs *inputs)
  303. {
  304.   if(inputs->Keys && inputs->Window)
  305.     IUpdateKeys(inputs);
  306.  
  307.   if(inputs->Ports[0]->Type)
  308.     IUpdatePort(inputs, 0);
  309.  
  310.   if(inputs->Ports[1]->Type)
  311.     IUpdatePort(inputs, 1);
  312. }
  313.  
  314. void IUpdateKeys(struct Inputs *inputs)
  315. {
  316.   struct IntuiMessage *im;
  317.   struct MenuItem   *mitem;
  318.   ULONG       imclass;
  319.   UWORD       imcode;
  320.   UWORD       imqual;
  321.  
  322.   while((im = (struct IntuiMessage *) GetMsg(inputs->Window->UserPort)))
  323.   {
  324.     imclass = im->Class;
  325.     imcode  = im->Code;
  326.     imqual  = im->Qualifier;
  327.  
  328.     ReplyMsg((struct Message *) im);
  329.  
  330.     switch(imclass)
  331.     {
  332.       case IDCMP_RAWKEY:
  333.         if(!(imqual & IEQUALIFIER_REPEAT) && inputs->RawKeys[imcode & IKEY_RAWMASK])
  334.         {
  335.           if(imcode & IECODE_UP_PREFIX)
  336.             inputs->Keys[inputs->RawKeys[imcode & IKEY_RAWMASK]] = 0;
  337.           else
  338.             inputs->Keys[inputs->RawKeys[imcode & IKEY_RAWMASK]] = 1;
  339.         }
  340.         break;
  341.  
  342.       case IDCMP_MENUPICK:
  343.         if(inputs->MenuHook)
  344.         {
  345.           while(imcode != MENUNULL)
  346.           {
  347.             CallHook(inputs->MenuHook, NULL, ITEMNUM(imcode));
  348.  
  349.             mitem = ItemAddress(inputs->Window->MenuStrip, imcode);
  350.             imcode  = mitem->NextSelect;
  351.           }
  352.         }
  353.         break;
  354.  
  355.       case IDCMP_REFRESHWINDOW:
  356.         BeginRefresh(inputs->Window);
  357.         if(inputs->RefreshHook)
  358.           CallHookPkt(inputs->RefreshHook, NULL, NULL);
  359.         EndRefresh(inputs->Window, TRUE);
  360.         break;
  361.  
  362.       case IDCMP_ACTIVEWINDOW:
  363.         IEnable(inputs);
  364.         break;
  365.  
  366.       case IDCMP_INACTIVEWINDOW:
  367.         IDisable(inputs);
  368.         break;
  369.  
  370.       default:
  371.         if(inputs->IDCMPHook)
  372.           CallHook(inputs->IDCMPHook, NULL, imclass);
  373.     }
  374.   }
  375. }
  376.  
  377. void IAllocPort(struct Inputs *inputs, LONG portnum)
  378. {
  379.   struct IPort  *port;
  380.   struct IOStdReq *io;
  381.  
  382.   port  = inputs->Ports[portnum];
  383.   io    = NULL;
  384.  
  385.   if(inputs->LowLevelBase)
  386.   {
  387.     switch(port->Type)
  388.     {
  389.       case IPT_JOYSTICK:
  390.         SetJoyPortAttrs(portnum, SJA_Type, SJA_TYPE_JOYSTK, TAG_END);
  391.         break;
  392.  
  393.       case IPT_MOUSE:
  394.         SetJoyPortAttrs(portnum, SJA_Type, SJA_TYPE_MOUSE, TAG_END);
  395.         break;
  396.  
  397.       case IPT_JOYPAD:
  398.         SetJoyPortAttrs(portnum, SJA_Type, SJA_TYPE_GAMECTLR, TAG_END);
  399.         break;
  400.     }
  401.   }
  402.   else
  403.   {
  404.     port->MsgPort = CreateMsgPort();
  405.  
  406.     if(port->MsgPort)
  407.     {
  408.       io  = (struct IOStdReq *) CreateIORequest(port->MsgPort, sizeof(struct IOStdReq));
  409.  
  410.       if(io)
  411.         OpenDevice("gameport.device", portnum, (struct IORequest *) io, 0);
  412.     }
  413.   }
  414.  
  415.   port->PortRequest = io;
  416.  
  417.   if(inputs->LowLevelBase || io)
  418.   {
  419.     if(port->AutoFireTime || port->BlueEmuTime)
  420.     {
  421.       if(!port->MsgPort)
  422.         port->MsgPort = CreateMsgPort();
  423.  
  424.       if(port->MsgPort)
  425.       {
  426.         port->TimerRequest  = CreateIORequest(port->MsgPort, sizeof(struct timerequest));
  427.  
  428.         if(port->TimerRequest)
  429.           OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *) port->TimerRequest, 0);
  430.       }
  431.     }
  432.  
  433.     IEnablePort(inputs, portnum);
  434.   }
  435. }
  436.  
  437. void IFreePort(struct Inputs *inputs, LONG portnum)
  438. {
  439.   struct IPort  *port;
  440.  
  441.   IDisablePort(inputs, portnum);
  442.  
  443.   port  = inputs->Ports[portnum];
  444.  
  445.   if(port->PortRequest)
  446.   {
  447.     if(port->PortRequest->io_Device)
  448.       CloseDevice((struct IORequest *) port->PortRequest);
  449.  
  450.     DeleteIORequest((struct IORequest *) port->PortRequest);
  451.   }
  452.  
  453.   if(port->TimerRequest)
  454.   {
  455.     CloseDevice((struct IORequest *) port->TimerRequest);
  456.     DeleteIORequest((struct IORequest *) port->TimerRequest);
  457.   }
  458.  
  459.   if(port->MsgPort)
  460.     DeleteMsgPort(port->MsgPort);
  461.  
  462.   if(inputs->LowLevelBase)
  463.     SetJoyPortAttrs(portnum, SJA_Reinitialize, NULL, TAG_END);
  464. }
  465.  
  466. void IEnablePort(struct Inputs *inputs, LONG portnum)
  467. {
  468.   struct IPort  *port;
  469.   struct IOStdReq *io;
  470.  
  471.   port  = inputs->Ports[portnum];
  472.  
  473.   if(!port->Enabled && port->PortRequest && port->PortRequest->io_Device)
  474.   {
  475.     struct GamePortTrigger  trigger;
  476.     UBYTE         type;
  477.  
  478.     if((port->Type == IPT_JOYSTICK) || (port->Type == IPT_JOYPAD))
  479.     {
  480.       trigger.gpt_Keys  = GPTF_UPKEYS|GPTF_DOWNKEYS;
  481.       trigger.gpt_Timeout = 0xffff;
  482.       trigger.gpt_XDelta  = 1;
  483.       trigger.gpt_YDelta  = 1;
  484.       type        = GPCT_ABSJOYSTICK;
  485.     }
  486.     else if(port->Type == IPT_MOUSE)
  487.     {
  488.       trigger.gpt_Keys  = GPTF_UPKEYS|GPTF_DOWNKEYS;
  489.       trigger.gpt_Timeout = 0xffff;
  490.       trigger.gpt_XDelta  = 10;
  491.       trigger.gpt_YDelta  = 10;
  492.       type        = GPCT_MOUSE;
  493.     }
  494.  
  495.     io  = port->PortRequest;
  496.  
  497.     io->io_Command  = GPD_ASKCTYPE;
  498.     io->io_Flags  = IOF_QUICK;
  499.     io->io_Data   = (APTR) &port->OldType;
  500.     io->io_Length = 1;
  501.     DoIO((struct IORequest *) io);
  502.     io->io_Command  = GPD_SETCTYPE;
  503.     io->io_Flags  = IOF_QUICK;
  504.     io->io_Data   = (APTR) &type;
  505.     io->io_Length = 1;
  506.     DoIO((struct IORequest *) io);
  507.     io->io_Command  = GPD_ASKTRIGGER;
  508.     io->io_Flags  = IOF_QUICK;
  509.     io->io_Data   = (APTR) &port->OldTrigger;
  510.     io->io_Length = sizeof(struct GamePortTrigger);
  511.     DoIO((struct IORequest *) io);
  512.     io->io_Command  = GPD_SETTRIGGER;
  513.     io->io_Flags  = IOF_QUICK;
  514.     io->io_Data   = (APTR) &trigger;
  515.     io->io_Length = sizeof(struct GamePortTrigger);
  516.     DoIO((struct IORequest *) io);
  517.     io->io_Command  = CMD_CLEAR;
  518.     io->io_Flags  = IOF_QUICK;
  519.     io->io_Data   = NULL;
  520.     io->io_Length = 0;
  521.     DoIO((struct IORequest *) io);
  522.     io->io_Command  = GPD_READEVENT;
  523.     io->io_Flags  = 0;
  524.     io->io_Data   = (APTR) &port->InputEvent;
  525.     io->io_Length = sizeof(struct InputEvent);
  526.     SendIO((struct IORequest *) io);
  527.  
  528.     port->PortRequestActive = TRUE;
  529.   }
  530.  
  531.   port->Enabled = TRUE;
  532. }
  533.  
  534. void IDisablePort(struct Inputs *inputs, LONG portnum)
  535. {
  536.   struct IPort  *port;
  537.   struct IOStdReq *io;
  538.   struct Message  *msg;
  539.  
  540.   port  = inputs->Ports[portnum];
  541.  
  542.   if(port->Enabled)
  543.   {
  544.     io  = port->PortRequest;
  545.  
  546.     if(port->PortRequestActive)
  547.       AbortIO((struct IORequest *) io);
  548.  
  549.     if(port->TimerRequestActive)
  550.       AbortIO((struct IORequest *) port->TimerRequest);
  551.  
  552.     while(port->PortRequestActive || port->TimerRequestActive)
  553.     {
  554.       WaitPort(port->MsgPort);
  555.  
  556.       while((msg = GetMsg(port->MsgPort)))
  557.       {
  558.         if(msg == (struct Message *) io)
  559.           port->PortRequestActive   = FALSE;
  560.         else
  561.           port->TimerRequestActive  = FALSE;
  562.       }
  563.     }
  564.  
  565.     if(io)
  566.     {
  567.       if(io->io_Device)
  568.       {
  569.         io->io_Command  = GPD_SETCTYPE;
  570.         io->io_Flags  = IOF_QUICK;
  571.         io->io_Data   = (APTR) &port->OldType;
  572.         io->io_Length = 1;
  573.         DoIO((struct IORequest *) io);
  574.         io->io_Command  = GPD_SETTRIGGER;
  575.         io->io_Flags  = IOF_QUICK;
  576.         io->io_Data   = (APTR) &port->OldTrigger;
  577.         io->io_Length = sizeof(struct GamePortTrigger);
  578.         DoIO((struct IORequest *) io);
  579.         io->io_Command  = CMD_CLEAR;
  580.         io->io_Flags  = IOF_QUICK;
  581.         io->io_Data   = NULL;
  582.         io->io_Length = 0;
  583.         DoIO((struct IORequest *) io);
  584.       }
  585.     }
  586.   }
  587.  
  588.   port->Enabled = FALSE;
  589. }
  590.  
  591. void IUpdatePort(struct Inputs *inputs, LONG portnum)
  592. {
  593.   struct IPort    *port;
  594.   struct Message    *msg;
  595.   struct InputEvent *ie;
  596.   LONG        button;
  597.   LONG        red;
  598.  
  599.   port  = inputs->Ports[portnum];
  600.   ie    = &port->InputEvent;
  601.   red   = port->RealRed;
  602.  
  603.   if(inputs->LowLevelBase)
  604.   {
  605.     button  = ReadJoyPort(portnum);
  606.  
  607.     red = (button & JPF_BUTTON_RED) ? 1 : 0;
  608.  
  609.     if(!port->AutoFireTime || port->BlueEmuTime)
  610.       port->Blue  = (button & JPF_BUTTON_BLUE) ? 1 : 0;
  611.  
  612.     port->Green   = (button & JPF_BUTTON_GREEN) ? 1 : 0;
  613.     port->Yellow  = (button & JPF_BUTTON_YELLOW) ? 1 : 0;
  614.     port->Forward = (button & JPF_BUTTON_FORWARD) ? 1 : 0;
  615.     port->Reverse = (button & JPF_BUTTON_REVERSE) ? 1 : 0;
  616.     port->Play    = (button & JPF_BUTTON_PLAY) ? 1 : 0;
  617.  
  618.     if((port->Type == IPT_JOYSTICK) || (port->Type == IPT_JOYPAD))
  619.     {
  620.       port->Move.Joystick.Up    = (button & JPF_JOY_UP) ? 1 : 0;
  621.       port->Move.Joystick.Down  = (button & JPF_JOY_DOWN) ? 1 : 0;
  622.       port->Move.Joystick.Left  = (button & JPF_JOY_LEFT) ? 1 : 0;
  623.       port->Move.Joystick.Right = (button & JPF_JOY_RIGHT) ? 1 : 0;
  624.     }
  625.     else if(port->Type == IPT_MOUSE)
  626.     {
  627.       LONG  delta;
  628.  
  629.       delta = (button & JP_MHORZ_MASK) - port->Move.Mouse.PrevX;
  630.  
  631.       port->Move.Mouse.PrevX  = (button & JP_MHORZ_MASK);
  632.       port->Move.Mouse.MouseX += delta;
  633.  
  634.       if(delta < -128)
  635.         port->Move.Mouse.MouseX += 256;
  636.       else if(delta > 127)
  637.         port->Move.Mouse.MouseX -= 256;
  638.  
  639.       delta = ((button & JP_MVERT_MASK) >> 8) - port->Move.Mouse.PrevY;
  640.  
  641.       port->Move.Mouse.PrevY  = (button & JP_MVERT_MASK) >> 8;
  642.       port->Move.Mouse.MouseY += delta;
  643.  
  644.       if(delta < -128)
  645.         port->Move.Mouse.MouseY += 256;
  646.       else if(delta > 127)
  647.         port->Move.Mouse.MouseY -= 256;
  648.     }
  649.   }
  650.  
  651.   if(port->MsgPort)
  652.   {
  653.     while((msg  = GetMsg(port->MsgPort)))
  654.     {
  655.       if((msg == (struct Message *) port->PortRequest)
  656.       && (port->PortRequest->io_Actual == sizeof(struct InputEvent)))
  657.       {
  658.         if(ie->ie_Code & IECODE_UP_PREFIX)
  659.           button = 0;
  660.         else
  661.           button = 1;
  662.  
  663.         switch(ie->ie_Code & (~IECODE_UP_PREFIX))
  664.         {
  665.           case IECODE_LBUTTON:
  666.             red     = button;
  667.             break;
  668.           case IECODE_RBUTTON:
  669.             if(!port->AutoFireTime || port->BlueEmuTime)
  670.               port->Blue  = button;
  671.             break;
  672.           case IECODE_MBUTTON:
  673.             port->Green = button;
  674.             break;
  675.         }
  676.  
  677.         if((port->Type == IPT_JOYSTICK) || (port->Type == IPT_JOYPAD))
  678.         {
  679.           switch(ie->ie_X)
  680.           {
  681.             case 0:
  682.               port->Move.Joystick.Left  = 0;
  683.               port->Move.Joystick.Right = 0;
  684.               break;
  685.             case -1:
  686.               port->Move.Joystick.Left  = 1;
  687.               port->Move.Joystick.Right = 0;
  688.               break;
  689.             case 1:
  690.               port->Move.Joystick.Left  = 0;
  691.               port->Move.Joystick.Right = 1;
  692.               break;
  693.           }
  694.           switch(ie->ie_Y)
  695.           {
  696.             case 0:
  697.               port->Move.Joystick.Up    = 0;
  698.               port->Move.Joystick.Down  = 0;
  699.               break;
  700.             case -1:
  701.               port->Move.Joystick.Up    = 1;
  702.               port->Move.Joystick.Down  = 0;
  703.               break;
  704.             case 1:
  705.               port->Move.Joystick.Up    = 0;
  706.               port->Move.Joystick.Down  = 1;
  707.               break;
  708.           }
  709.         }
  710.         else if(port->Type == IPT_MOUSE)
  711.         {
  712.           port->Move.Mouse.MouseX += ie->ie_X;
  713.           port->Move.Mouse.MouseY += ie->ie_Y;
  714.         }
  715.  
  716.         port->PortRequest->io_Command = GPD_READEVENT;
  717.         port->PortRequest->io_Flags   = 0;
  718.         port->PortRequest->io_Data    = (APTR) ie;
  719.         port->PortRequest->io_Length  = sizeof(struct InputEvent);
  720.         SendIO((struct IORequest *) port->PortRequest);
  721.       }
  722.             else if(msg == (struct Message *) port->TimerRequest)
  723.       {
  724.         port->TimerRequestActive  = FALSE;
  725.  
  726.         if((port->TimerRequest->tr_node.io_Error != IOERR_ABORTED) && red)
  727.         {
  728.           if(port->AutoFireTime)
  729.           {
  730.             if(port->Red)
  731.               port->Red = 0;
  732.             else
  733.               port->Red = 1;
  734.  
  735.             port->TimerRequest->tr_node.io_Command  = TR_ADDREQUEST;
  736.             port->TimerRequest->tr_node.io_Flags  = 0;
  737.             port->TimerRequest->tr_time.tv_secs   = 0;
  738.             port->TimerRequest->tr_time.tv_micro  = port->AutoFireTime;
  739.  
  740.             SendIO((struct IORequest *) port->TimerRequest);
  741.  
  742.             port->TimerRequestActive  = TRUE;
  743.           }
  744.           else
  745.           {
  746.             port->Red = 0;
  747.             port->Blue  = 1;
  748.           }
  749.         }
  750.       }
  751.     }
  752.   }
  753.  
  754.   if(port->RealRed != red)
  755.   {
  756.     port->Red = red;
  757.  
  758.     if(port->TimerRequest)
  759.     {
  760.       if(!port->AutoFireTime || port->BlueEmuTime)
  761.         port->Blue  = 0;
  762.  
  763.       if(red)
  764.       {
  765.         if(port->TimerRequest && port->TimerRequest->tr_node.io_Device && !port->TimerRequestActive)
  766.         {
  767.           port->TimerRequest->tr_node.io_Command  = TR_ADDREQUEST;
  768.           port->TimerRequest->tr_node.io_Flags  = 0;
  769.           port->TimerRequest->tr_time.tv_secs   = 0;
  770.  
  771.           if(port->AutoFireTime)
  772.             port->TimerRequest->tr_time.tv_micro  = port->AutoFireTime;
  773.           else
  774.             port->TimerRequest->tr_time.tv_micro  = port->BlueEmuTime;
  775.  
  776.           SendIO((struct IORequest *) port->TimerRequest);
  777.  
  778.           port->TimerRequestActive  = TRUE;
  779.         }
  780.       }
  781.       else
  782.       {
  783.         if(port->TimerRequestActive)
  784.           AbortIO((struct IORequest *) port->TimerRequest);
  785.       }
  786.     }
  787.   }
  788.  
  789.   port->RealRed = red;
  790. }
  791.  
  792. /*************************************************************************************************/
  793.